/*
 * DbRow.h
 *
 *  Created on: 2018年1月3日
 *      Author: chuanjiang.zh@qq.com
 */

#ifndef DBROW_H_
#define DBROW_H_

#include "DbType.h"
#include <sstream>


namespace db
{

enum DataType
{
    DT_NULL = -1,
    DT_STRING, DT_DATE, DT_DOUBLE, DT_INTEGER, DT_LONG_LONG, DT_UNSIGNED_LONG_LONG,
    DT_BLOB, DT_XML
};


class DbRow
{
public:
	static bool get(soci::row& row, size_t pos, int& value);
	static bool get(soci::row& row, size_t pos, int64_t& value);
	static bool get(soci::row& row, size_t pos, std::string& value);
	static bool get(soci::row& row, size_t pos, double& value);
	static bool getTime(soci::row& row, size_t pos, time_t& value);

	static bool get(soci::row& row, const std::string& name, int& value);
	static bool get(soci::row& row, const std::string& name, int64_t& value);
	static bool get(soci::row& row, const std::string& name, std::string& value);
	static bool get(soci::row& row, const std::string& name, double& value);
	static bool getTime(soci::row& row, const std::string& name, time_t& value);

	static bool isNull(soci::row& row, size_t pos);

    template < class T >
    static bool getValue(soci::row& row, const std::string& name, T& value)
    {
        std::string str;
        if (!get(row, name, str))
        {
            return false;
        }

        std::istringstream iss(str);
        iss >> value;
        return true;
    }
        

public:
	explicit DbRow(soci::row& row);
	virtual ~DbRow();

	soci::row& get();

	bool get(size_t pos, int& value);
	bool get(size_t pos, int64_t& value);
	bool get(size_t pos, std::string& value);
	bool get(size_t pos, double& value);
    
	bool getTime(size_t pos, time_t& value);

	bool get(const std::string& name, int& value);
	bool get(const std::string& name, int64_t& value);
	bool get(const std::string& name, std::string& value);
	bool get(const std::string& name, double& value);
	bool getTime(const std::string& name, time_t& value);

	bool getValue(size_t pos, std::string& value)
	{
		return get(pos, value);
	}

	bool getValue(size_t pos, int& value)
	{
		return get(pos, value);
	}

	bool getValue(size_t pos, double& value)
	{
		return get(pos, value);
	}

	bool getValue(size_t pos, int64_t& value)
	{
		return get(pos, value);
	}



    template < class T >
    bool getValue(size_t pos, T& value)
    {
        std::string str;
        if (!get(pos, str))
        {
            return false;
        }

        std::istringstream iss(str);
        iss >> value;
        return true;
    }

	bool getValue(const std::string& name, std::string& value)
	{
		return get(name, value);
	}

	bool getValue(const std::string& name, int& value)
	{
		return get(name, value);
	}

	bool getValue(const std::string& name, double& value)
	{
		return get(name, value);
	}

	bool getValue(const std::string& name, int64_t& value)
	{
		return get(name, value);
	}

    template < class T >
    bool getValue(const std::string& name, T& value)
    {
        std::string str;
        if (!get(name, str))
        {
            return false;
        }

        std::istringstream iss(str);
        iss >> value;
        return true;
    }

	int opt(size_t pos, int value);
	int64_t opt(size_t pos, int64_t value);
	std::string opt(size_t pos, const std::string& value);
	double opt(size_t pos, double value);
	time_t optTime(size_t pos, time_t value);

	int opt(const std::string& name, int value);
	int64_t opt(const std::string& name, int64_t value);
	std::string opt(const std::string& name, const std::string& value);
	double opt(const std::string& name, double value);
	time_t optTime(const std::string& name, time_t value);

    bool isNull(size_t pos);

    size_t size() const;

    std::string getName(size_t idx) const;

    DataType getType(size_t idx) const;


protected:
	soci::row&	m_row;

};


} /* namespace db */

#endif /* DBROW_H_ */
